# -*- coding: utf-8 -*-


# Tâches devant être réalisée : expressions minimes / génération
# re.IGNORECASE
import os
import urllib
import re
import math
# Objet tfidf associé à chacune des objets à analyser
class tfidf():
    
    objet_associe = None
    tfidf = None
    dic_result_processing = None

class parse_c():
    
    dico = None
    dico_lemme_occur = None
    dj = None 
    
    # Récupération en entrée d'une liste d'objets 
    # contenant le titre / le sigle / descriptif du cours
    def process (self,data,keys):
        # Initialisation de paramètres
        #espaceur = "</BR>\n"

       
            # Mise en forme des données 
            
        # Transformation en lemme
        data_lemme = self.keyword_to_lemme(data)
        keys_lemme =  self.keyword_to_lemme(keys)
        print "KEY LIST"
        print keys_lemme
        print "DATA LEMME"
        print data_lemme
        self.dictio_lemme_occur(data_lemme[1])
        
        result_list = self.lookup_lemm_in_data(keys_lemme)        
            # Recherche des mots clés dans la liste d'objet fournie
        dico_test = dict(result_list)
        print "Match List"
        print result_list[0]
        print "Fail List"
        print result_list[1]
        return_char = "OK"
            
        return return_char
    
    # dfj appele pour chacun des mots clés utilisé 
    def dfj_computation (self,keys_lemme, objects_list):
        dfj = 0
        dict_dfj = None
        local_list = []
        for key in keys_lemme[1] :    
            for object in objects_list :
                if key in object.dic_result_processing :
                    dfj+=1
            local_list.append((key),(dfj))
            djf = 0
        dict_dfj = dict(local_list)
            
        

    
    def tfidf_computation (self,input, keys_lemme,dict_dfj):
        #tfij : frequence du terme (term frequency) qui correspond
        #au nombre d'occurences du terme tj dans le
        #document Di
        
        
        # Récupération du dfj 
        # Test sur le type des données en entrées ?
        # Pour chacun des mots-cles 
        for key in keys_lemme[1] :
            # Pour chacun des documents
            try :
                dfj = eval(dict_dfj[key])    
            except :
                pass    
            for objet in input :
                # Récupère les caractéristique de l'objet
                # On a bien dic_result_processing si le mots n'a pas d'occurence 
                dic_proc = objet.dic_result_processing
                tfij = eval(dic_proc[key])
                dj = self.dj
                tfidf = 0
                try :
                    idfj = math.log(dj/dfj)
                except : 
                    print "LOG / DIV ET 0 CA MARCHE PAS !"
                tfidf = idfj*tfij
                objet.tfidf +=tfidf
        return "OK"
    
    def max_tfdif_finder(self,input):
        max_local = 0
        objet_local = None
        for object in input :
            if object.tfidf > max_local :
                 object_local = object
        return object_local
                
        
    
    
    
    
    #dfj : frequence des documents (document frequency) qui correspond au nombre de documents qui contiennent
    # le terme tj


#idfj = log(d/dfj)  frequence inverse des documents (inverse #document frequency) qui repréesente une mesure de la spécificite du terme j. 
#d est le nombre total de documents

# tfidf = tf * idf valeur pondérée de la fréquuence de termes
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # On prend la liste triée composée des lemmes et des mots n'ayant pas de lemme
    # Pour chacun des mots on compte l'occurence et on cré un dictionnaire ayant les caractéristiques suivantes :
    # lemme  : occurence
    
    def dictio_lemme_occur(self,liste):
        temp=[]
        for entry in liste :
            occur = liste.count(entry)
            temp.append((entry,occur))
        self.dico_lemme_occur = dict(temp)
        return True
    
    # Fonction de recherche de lemmes dans des données mis sous la forme d'un dictionnaire
    
    def lookup_lemm_in_data(self,data):
        match_list=[]
        unmatched_list=[]
        for key in data[0] :                                                # Recherche avec la succed liste
            print key
            if key in self.dico_lemme_occur :
                print key
                match_list.append((key,self.dico_lemme_occur[key]))
            else :
                unmatched_list.append(key)
        for key in data[1] :                                                # Recherche avec la fail-liste
            print key
            if key in self.dico_lemme_occur :
                print key
                match_list.append((key,self.dico_lemme_occur[key]))
            else :
                unmatched_list.append(key)
        return (match_list,unmatched_list)
            

                                                            
    # 2nde fonction de recherche dans un dictionnaire 
    # Paramètres d'entrées : # liste dont les éléments sont les mots à analyser
    #                         # dictionnaire de référence
    
    # Test à réaliser : envoie un mot pas dans un dic un mot dans le dic et fornat de sortie
    def last_lookup(self,mot):
                                                                                    # Initialisation
        fail_list = []
        lemme_list = []                                                                        # Gestion des erreurs lors de la recherche dans le dictionnaire                                                                                  # Pour chacun des mots de la liste 
        mot_compose = re.findall(r'[\w]+',mot,re.U)                                         # on remplace les ' et - par des espaces et l'on crée une nouvelle liste ERRRREUR                                                                      # Pour chacun des mots contenus dans la liste découpée
        for mot  in mot_compose :
            if (mot == "") :                                                    # On ignore le caractère vide
                continue
            else : 
                try :                                                           # Sinon 
                    lemme_list.append(self.dico[mot])                            # Récupération du nombre de syllabe(s) associées
                except KeyError :                                               # Erreur traitée : mots non présent dans le dico
                    fail_list.append(mot)                                       # Ajout du mot non traité à la liste de retour
        result_liste =[fail_list,lemme_list]                                 # Création de la liste de retour
        return result_liste    
    
        # On essaie de trouver un lemme à partir de la combinaison de deux mots
    
    
    def two_words_in_one_lookup (self,liste):
        
        # Initialisation
        new_lemme=[]
        fail_list = []
        if ((liste[0] + " " + liste[1]) in self.dico) :
            new_mot = liste[0] + " " + liste[1]
            new_lemme = self.dico[new_mot]                                     # Calcul du nombre de syllabes correspondantes
        else :                                                                        
            fail_list.append(liste[0])                                              # Sinon on ajoute les deux mots à la liste des mots 
            fail_list.append(liste[1])                                              # non traités  
        return_list = [fail_list, new_lemme]                               # Création de la liste de retour
        return return_list
    
    
    
    # Fonction de transformation d'une chaine de caractère une une liste de lemme associée
    # Paramètres d'entrée : # Liste dont les éléments sont les mots à analyser
    #                        # Dicionnaire 
    # Paramètre de retour : # Liste contenant les mots non trouvés, et pour les recherche valide, le nombre de syllabes et mots trouvés    
    #Test un mot non dictionnaire, un mot double et un mot dans le dic et comparaison par rapport à valeur attendu
        
# Pour chacun des mots clé contenues dans le string passé, on cherche on cherche le lemme associé, et on retourne la liste 
# des lemmes et la liste des mots dont la recherche de lemme n'a pas abouti
        
    def keyword_to_lemme (self, data_string):
        # Mise en forme de la liste 
        data_string = data_string.lower().decode('utf8 ')
        data_string=re.findall(r'[\w\-\']+',data_string,re.UNICODE)
        # Initialisation
        lemme_list=[]
        fail_list = []
        tampon =['']*2                                   # Variable tampon pour contenir deux mots à analyser de manière conjointe
        for mot in data_string:                                # Pour chacun des mots contenus dans la liste
            if mot == "":                                # On ignore le caractère vide 
                continue
            elif mot in self.dico :                      # si le mot est dans le dictionnaire
                lemme_list.append(self.dico[mot])        # Calcul du nombre de syllabes
                tampon[0]= mot                           # Mise en mémoire du dernier mot matché
            else :
                tampon[1]=mot                                    # Mise en mémoire du mot non matché
                result =self.two_words_in_one_lookup(tampon)     # Tentative de combiner les deux mots 
                if result[1] != []:                              # Si match alors 
                    try : 
                        lemme_list.remove(tampon[0])
                    except ValueError :
                        print "Un cas bizare"  
                else :
                    result = self.last_lookup(mot)
                    if result[1] !=[]:
                        for mots in result[1]:
                            lemme_list.append(mots)
                    if result[0] !=[]:
                        for mots in result[0]:
                            fail_list.append(result[0])
                tampon[0]=mot 
        # Mise à jour des valeurs
        return_list = [fail_list, lemme_list]            # Création de la liste de retour
        print "RETURN LIST"
        print return_list
        return return_list
    
    
    # On transofrme les données en entrées vers un format exploitable ie :
    # un dictionnaire avec pour chaque mot le nombre d'itération 
            
    # Fonction de création d'un dictionnaire 
    # Paramètres d'entrées : # lexique
    #                         # Nombre de lignes présentes au début du texte à ignorer
    #                         # Position dans le lexique du mot servant de clé au dictionnaire
    #                         # Position dans le lexique du nombre de syllabe servant de résultat dans le dico
           
    
    
    def create_dictionary(self,file_in,ind1,ind2,ind3):
        liste = file_in.split("\n")
        # Suppression des "ind1" premières colones inutiles (données de type descriptive)
        del liste[:ind1]
        l=[]
        for i in liste:                                                     # Pour chacune des lignes 
            i = i.split("\t")                                               # Création d'une liste contenant les différentes info pour chaque mot
            if (len(i) < ind3) :                                            # Vérification en cas d'irrégularité du lexique
                continue
            else :                                                          # Création d'une liste contenant le mots et le nombre de syllabes associées
                l.append((i[ind2], i[ind3]))                                # position 0 et 3 pour nous
        self.dico = dict(l)                                                 # Création du dictionnaire    
        
        
    
    def dictionnaire_init (self):
        #on verifi la presence du dico dans le repertoir de travail. 
        #Si on ne le trouve pas un essai de le recuperer sur le web
        localdic="./Lexique372.txt"
        if os.path.isfile(localdic):
            print "travail a partir de la version local du dictionnaire"
            file_in =open(localdic)
        else :
            try : 
                urldic= "http://www.cours.polymtl.ca/inf8007/Tp/20121/Lexique372.txt"
                print "recuperation de la version distante du dictionnaire..."
                print urldic
                file_in = urllib.urlopen(urldic)
            except :
                print "erreur lors de la tentative de recuperation du dictionnaire !"
                return False
            
        file_in = file_in.read().decode('latin1 ').encode ('utf8 ').decode('utf8')

        
        self.create_dictionary( file_in,0,0,2) # lemme est la troisième entrée
        return True



if __name__ == '__main__':
    print "test du module de parse..."
    data = "Projet individuel choisi par l'étudiant et réalisé sous la direction d'un professeur du département de génie mécanique ou de tout autre ingénieur agréé par le département. La responsabilité de l'ensemble du travail est assumée par l'étudiant. Le projet doit être approuvé par le responsable du projet intégrateur III du département de génie mécanique. Le projet fait l'objet d'un rapport qui doit présenter l'état de la question, le développement de la solution choisie, les résultats et les conclusions. Le rapport doit aussi contenir une section sur la gestion du projet ainsi qu'une section décrivant les matières intégrées lors du projet. Le projet fait l'objet d'une présentation orale publique devant un jury d'évaluation composé de professeurs."
    keys = " Projet mécanique"
    analyser = parse_c()
    if analyser.dictionnaire_init():
        print "< OK >"
    analyser.process(data,keys)
        
